﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.Statistics.RandomNumberGenerator
{
    /// <summary>
    /// This class adapts the standard random engine of the .NET framework.
    /// </summary>
    [Serializable]
    public class StandardRandomGenerator : AbstractRandomGenerator
    {
        /// <summary>
        /// Holds the standard radom engine of the .NET framework.
        /// </summary>
        private readonly Random engine;

        /// <summary>
        /// Initializes a new instance of the <see cref="StandardRandomGenerator"/> class.
        /// </summary>
        public StandardRandomGenerator()
            : base((uint) DateTime.Now.Millisecond)
        {
            this.engine = new Random((int) this.Seed);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="StandardRandomGenerator"/> class.
        /// </summary>
        /// <param name="seed">A number used to calculate a starting value for the pseudo-random number sequence.
        /// If a negative number is specified, the absolute value of the number is used.</param>
        public StandardRandomGenerator(uint seed)
            : base(seed)
        {
            this.engine = new Random((int) seed);
        }

        /// <summary>
        /// Returns a nonnegative random number.
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer greater than or equal to zero and less than maximum integer value.
        /// </returns>
        public override int Next()
        {
            return this.engine.Next();
        }

        /// <summary>
        /// Nexts the specified max value.
        /// </summary>
        /// <param name="maxValue">Returns a nonnegative random number less than the specified maximum.</param>
        /// <returns>
        /// A 32-bit signed integer greater than or equal to zero and less than maximum integer value.
        /// </returns>
        public override int Next(int maxValue)
        {
            return this.engine.Next(maxValue);
        }

        /// <summary>
        /// Returns a random number within a specified range.
        /// </summary>
        /// <param name="minValue">The inclusive lower bound of the random number returned.</param>
        /// <param name="maxValue">The exclusive upper bound of the random number returned. maxValue must be
        /// greater than or equal to minValue.</param>
        /// <returns>
        /// A 32-bit signed integer greater than or equal to zero and less than maximum integer value.
        /// </returns>
        public override int Next(int minValue, int maxValue)
        {
            return this.engine.Next(minValue, maxValue);
        }

        /// <summary>
        /// Returns a random number between 0.0 and 1.0.
        /// </summary>
        /// <returns>
        /// A double-precision floating point number greater than or equal to 0.0, and less
        /// than 1.0.
        /// </returns>
        public override double NextDouble()
        {
            return this.engine.NextDouble();
        }
    }
}